package com.df.ez_game.server.logic.client;

import com.baidu.bjf.remoting.protobuf.Codec;
import com.baidu.bjf.remoting.protobuf.ProtobufProxy;
import com.df.ez_game.server.logic.TcpClientMsgCodec;
import com.df.ez_game.server.logic.module.equip.entity.WearEquipReq;
import com.df.ez_game.server.logic.module.equip.entity.WearEquipResp;
import com.df.ez_game.server.msg.client.ClientReqMsg;
import com.df.ez_game.server.msg.client.ClientRespMsg;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

public class TcpClient {
    private final String host;
    private final int port;

    public TcpClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();

                            pipeline.addLast(new LengthFieldBasedFrameDecoder(
                                    5*1024*1024,
                                    // 长度字段的偏移量， 不偏移
                                    0,
                                    // 字段的长度,
                                    4,
                                    // 要添加到长度字段值的补偿值：长度调整值 = 内容字段偏移量 - 长度字段偏移量 - 长度字段的字节数
                                    0,
                                    // 跳过的初始字节数： 跳过0位; (跳过消息头的 0 位长度)
                                    0));

                            //消息解析
                            pipeline.addLast(new TcpClientMsgCodec());

                            // 自定义业务处理器
                            pipeline.addLast(new SimpleChannelInboundHandler<ClientRespMsg>() {
                                @Override
                                protected void channelRead0(ChannelHandlerContext channelHandlerContext, ClientRespMsg clientRespMsg) throws Exception {
                                    int code = clientRespMsg.getCode();
                                    if(code!=0){
                                        System.out.println("请求返回错误码："+code);
                                        return;
                                    }
                                    byte[] data = clientRespMsg.getData();
                                    Codec<WearEquipResp> codec = ProtobufProxy.create(WearEquipResp.class);
                                    WearEquipResp decode = codec.decode(data);
                                    System.out.println("请求结果："+decode);
                                }
                            });
                        }
                    });

            // 连接服务器
            ChannelFuture future = bootstrap.connect(host, port).sync();
            System.out.println("客户端连接成功...");

            // 获取通道并发送消息
            Channel channel = future.channel();

            WearEquipReq wearEquipReq = new WearEquipReq();
            wearEquipReq.setHole(1).setEquipId(2);
            ClientReqMsg reqMsg = new ClientReqMsg();
            reqMsg.setMsgSerial(111);
            reqMsg.setCmd(1<<16|1);
            reqMsg.setVer(0);
            Codec<WearEquipReq> codec = ProtobufProxy.create(WearEquipReq.class);
            byte[] encode = codec.encode(wearEquipReq);
            reqMsg.setData(encode);


            // 等待连接关闭
            channel.closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new TcpClient("127.0.0.1", 6668).start();
    }
}
